package it.paceGiuseppe.sols.ciambelle;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MonitorCiambelle {
	
	private Lock lock = new ReentrantLock();
	
	private int numeroIngredienti = 0;
	
	private Condition codaGestoreIngredienti = lock.newCondition();
	private Condition codaGestoreNastroAttesaIngredienti = lock.newCondition();
	private Condition codaAttesaNastro = lock.newCondition();
	private Condition codaAttesaFornto = lock.newCondition();
	
	private boolean fornoLibero = true;
	private boolean nastroLibero = true;

	public void richiestaAggiuntaIngrediente() throws InterruptedException
	{
		lock.lock();
		
		while(numeroIngredienti == Impastatrice.C_MAX)
		{
			codaGestoreIngredienti.await();
		}
		
		numeroIngredienti++;
		
		lock.unlock();
	}
	
	public void fineAggiuntaIngrediente() throws InterruptedException
	{
		lock.lock();
		
		if(numeroIngredienti == Impastatrice.C_MAX)
		{
			codaGestoreNastroAttesaIngredienti.signal();
		}
		
		lock.unlock();
	}
	
	
	public void inizioSvuotamentoImpastatrice() throws InterruptedException
	{
		lock.lock();
		
		while(numeroIngredienti != Impastatrice.C_MAX)
		{
			codaGestoreNastroAttesaIngredienti.await();
		}
		
		lock.unlock();
	}
	
	public void fineSvuotamentoImpastratrice() throws InterruptedException
	{
		lock.lock();
		
		numeroIngredienti = 0;
		
		codaGestoreIngredienti.signal();
		
		lock.unlock();
	}
	
	public void acquisizioneNastro() throws InterruptedException
	{
		lock.lock();
		
		while(!nastroLibero)
			codaAttesaNastro.await();
		
		nastroLibero = false;
		
		lock.unlock();
	}
	
	public void rilascioNastro() throws InterruptedException
	{
		lock.lock();
		
		nastroLibero = true;
		
		codaAttesaNastro.signal();
		
		lock.unlock();
	}
	
	public void richiestaForno() throws InterruptedException
	{
		lock.lock();
		
		while(!fornoLibero)
		{
			codaAttesaFornto.await();
		}
		
		fornoLibero = false;
		
		lock.unlock();
	}
	
	public void rilascioForno() throws InterruptedException
	{
		lock.lock();
		
		fornoLibero = true;
		
		codaAttesaFornto.signal();
		lock.unlock();
	}
	
}
